﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using WYJCore.Extension;

namespace WYJWeb
{
    public static class ExpressionHelper
    {
        public static string Parse(this LambdaExpression expression)
        {
            return expression == null? "" : Visitor.Default.Parse(expression);
        }
    }

    public class Visitor : ExpressionVisitor
    {
        public static Visitor Default { get; set; } = new Visitor();


        internal string Parse(LambdaExpression expression)
        {
            SB = new StringBuilder();
            Visit(expression.Body);
            return SB.ToString();
        }

        public Dictionary<int,object> Parameters { get; private set; }

        protected StringBuilder SB;      

        protected override Expression VisitBinary(BinaryExpression node)
        {
            //SB.Append("(");
            Visit(node.Left);

            SB.Append(node.NodeType.TransferNodeType());

            Visit(node.Right);
            //SB.Append(")");

            return node;
        }
        protected override Expression VisitMember(MemberExpression node)
        {
            if (node.Expression is ParameterExpression)
            {
                SB.Append(node.Member.Name);
                return node;
            }
            else if (node.Expression is MemberExpression)
            {
                var f = Expression.Lambda(node).Compile();
                var value = f.DynamicInvoke();
                SB.Append("'" + value + "'");
            }
            return node;
        }

        protected override Expression VisitConstant(ConstantExpression node)
        {
            SB.Append("'" + node.Value + "'");
            return node;
        }

        protected override Expression VisitMethodCall(MethodCallExpression node)
        {
            return base.VisitMethodCall(node);
        }


        protected override Expression VisitConditional(ConditionalExpression node)
        {
            return base.VisitConditional(node);
        }
    }
}
